﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using Gavel.Common.Component.Resource;
using Gavel.Common.Utilities.Const;

namespace Gavel.Common.Component.Helper;

/// <summary>
/// 通知帮助类
/// </summary>
public class NotifyHelper
{
    #region 单例构造

    /// <summary>
    /// 单例锁
    /// </summary>
    private static readonly object Padlock = new();

    /// <summary>
    /// 单例对象
    /// </summary>
    private static readonly Lazy<NotifyHelper> LazyInstance = new(() => new NotifyHelper(), LazyThreadSafetyMode.ExecutionAndPublication);

    /// <summary>
    /// 私有化构造
    /// </summary>
    private NotifyHelper()
    {
        // 延迟初始化容器
        Application.Current.Dispatcher.Invoke(() =>
        {
            _container = new StackPanel
            {
                VerticalAlignment = VerticalAlignment.Top,
                HorizontalAlignment = HorizontalAlignment.Right,
                RenderTransform = new TranslateTransform() // 为动画准备
            };

            Window? main = Application.Current.MainWindow;
            if (main is null)
            {
                return;
            }


            Grid grid = new Grid();
            if (main.Content is UIElement content)
            {
                main.Content = null;
                grid.Children.Add(content);
            }

            grid.Children.Add(_container);
            Panel.SetZIndex(grid, int.MaxValue);
            main.Content = grid;
        }, DispatcherPriority.Loaded);
    }

    /// <summary>
    /// 单例对象
    /// </summary>
    public static NotifyHelper Instance
    {
        get
        {
            lock (Padlock)
            {
                return LazyInstance.Value;
            }
        }
    }

    #endregion 单例构造

    #region 字段属性

    /// <summary>
    /// 通知容器
    /// </summary>
    private StackPanel? _container;

    /// <summary>
    /// 通知子项列表
    /// </summary>
    private readonly List<NotificationItem> _notifications = [];

    /// <summary>
    /// 最大子项数量
    /// </summary>
    private const int MaxItemCount = 3;

    #endregion 字段属性

    #region 业务方法

    /// <summary>
    /// 显示一般提示
    /// </summary>
    /// <param name="message">通知消息</param>
    public void Info(string message) => ShowNotify(NotifyType.Info, message);

    /// <summary>
    /// 显示成功提示
    /// </summary>
    /// <param name="message">通知消息</param>
    public void Success(string message) => ShowNotify(NotifyType.Success, message);

    /// <summary>
    /// 显示告警提示
    /// </summary>
    /// <param name="message">通知消息</param>
    public void Warning(string message) => ShowNotify(NotifyType.Warning, message);

    /// <summary>
    /// 显示错误提示
    /// </summary>
    /// <param name="message">通知消息</param>
    public void Error(string message) => ShowNotify(NotifyType.Error, message);

    /// <summary>
    /// 展示通知
    /// </summary>
    /// <param name="type">通知类型</param>
    /// <param name="message">通知消息</param>
    private void ShowNotify(NotifyType type, string message)
    {
        Application.Current.Dispatcher.Invoke(() =>
        {
            NotificationItem notification = new NotificationItem(type, message);
            if (_notifications.Count >= MaxItemCount)
            {
                NotificationItem oldest = _notifications.First();
                RemoveNotification(oldest);
            }

            _container?.Children.Insert(0, notification);
            _notifications.Add(notification);

            notification.AppearAnimation();
            notification.AutoClose();
        });
    }

    /// <summary>
    /// 移除通知
    /// </summary>
    /// <param name="notification">通知</param>
    public void RemoveNotification(NotificationItem notification)
    {
        notification.DisappearAnimation(() =>
        {
            _container?.Children.Remove(notification);
            _notifications.Remove(notification);
        });
    }

    #endregion 业务方法
}